#pragma once
namespace graph
{
//Singletone, which stores all app data
struct global_data_t
{
    high_way_dict_t high_way_dict;
    graph_view_ptr_t all_way_view_;
    graph_view_ptr_t motor_way_view_;
    graph_view_ptr_t bicycle_view_;
    graph_view_ptr_t foot_way_view_t_;
    graph_view_ptr_t current_view_;
    std::string current_path_type_;
    graph_ptr_t graph_;
    
    global_data_t();
    void load_graph(std::string file_name, std::ostream& logger);
    void set_new_view(std::string path_type);
    graph_view_ptr_t get_current_view_for_graph(); 
};

struct global
{
   static global_data_t& get_instance()
   {
      return global_;
   }
private:
   static global_data_t global_;
};
inline global_data_t::global_data_t()
{
   //0 - reserved for no value
   //ATTENTION: IF CHANGED VALUES in osm, YOU HAVE TO SYNC WITH LOGIC OF
   high_way_dict[MOTORWAY_WAY_TAG] = MOTORWAY_WAY_KEY;
   high_way_dict[TRUNK_WAY_TAG] = TRUNK_WAY_KEY;
   high_way_dict[PRIMARY_WAY_TAG] = PRIMARY_WAY_KEY;
   high_way_dict[SECONDARY_WAY_TAG] = SECONDARY_WAY_KEY;
   high_way_dict[TERTIARY_WAY_TAG] = TERTIARY_WAY_KEY;
   high_way_dict[UNCLASSIFIED_WAY_TAG] = UNCLASSIFIED_WAY_KEY;
   high_way_dict[RESIDENTIAL_WAY_TAG] = RESIDENTIAL_WAY_KEY;
   high_way_dict[LIVING_STREET_WAY_TAG] = LIVING_STREET_WAY_KEY;
   high_way_dict[ROAD_WAY_TAG] = ROAD_WAY_KEY;
   high_way_dict[PEDESTRIAN_WAY_TAG] = PEDESTRIAN_WAY_KEY;
   high_way_dict[PATH_WAY_TAG] = PATH_WAY_KEY;
   high_way_dict[BRIDLEWAY_WAY_TAG] = BRIDLEWAY_WAY_KEY;
   high_way_dict[CYCLEWAY_WAY_TAG] = CYCLEWAY_WAY_KEY;
   high_way_dict[FOOTWAY_WAY_TAG] = FOOTWAY_WAY_KEY;
}
inline void global_data_t::load_graph(std::string file_name, std::ostream& logger)
{
   graph_ = graph_ptr_t(new graph_t(file_name, logger)); 

   all_way_view_ = graph_view_ptr_t(new all_way_view_t(graph_.get()));
   motor_way_view_ = graph_view_ptr_t(new motor_way_view_t(graph_.get()));
   bicycle_view_ = graph_view_ptr_t(new bicycle_view_t(graph_.get()));
   foot_way_view_t_ = graph_view_ptr_t(new foot_way_view_t(graph_.get()));

   set_new_view(PATH_TYPE_ALL);
}
inline void global_data_t::set_new_view(std::string path_type)
{
   current_path_type_ = path_type;
   if (path_type == graph::PATH_TYPE_ALL)
   {
      current_view_ = all_way_view_;
   }
   else if (path_type == graph::PATH_TYPE_MOTOR)
   {
      current_view_ = motor_way_view_;
   }
   else if (path_type == graph::PATH_TYPE_BICYCLE)
   {
      current_view_ = bicycle_view_;
   }
   else if (path_type == graph::PATH_TYPE_FOOT)
   {
      current_view_ = foot_way_view_t_;
   }
}

inline graph::graph_view_ptr_t global_data_t::get_current_view_for_graph()
{
   graph::graph_view_ptr_t view_ptr;
   if (current_path_type_ == graph::PATH_TYPE_ALL)
   {
      view_ptr.reset( new graph::all_way_view_t(graph_.get()));
   }
   else if (current_path_type_ == graph::PATH_TYPE_MOTOR)
   {
      view_ptr.reset( new graph::motor_way_view_t(graph_.get()));
   }
   else if (current_path_type_ == graph::PATH_TYPE_BICYCLE)
   {
      view_ptr.reset( new graph::bicycle_view_t(graph_.get()));
   }
   else if (current_path_type_ == graph::PATH_TYPE_FOOT)
   {
      view_ptr.reset( new graph::foot_way_view_t(graph_.get()));
   }
   return view_ptr;
}
}
